﻿using System.Collections.Generic;
using UnityEngine;
using Framework.Utils;
using BridgeShips.AI;
using System.Collections;
using Framework.Mathd;

namespace BridgeShips {
    public class ShipsSpawner : MonoBehaviour {

        [SerializeField]
        private bool m_ShowGUI = true;

        [SerializeField]
        private bool m_EnableSpawning = true;

        [SerializeField]
        [Space()]
        [Clamp( 0, 99 )]
        private int m_MaxCount = 35;

        [SerializeField]
        [Clamp( 0.1f, 2.0f )]
        private float m_SpawnInterval = 0.5f;

        [SerializeField]
        private GameObject[] m_Prefabs = null;
        [SerializeField]
        private GameObject m_BillBoard;
        [SerializeField]
        private Sprite[] m_BillBoardSprites;

        private float m_LastUpdateTime;

        private List<AIEventHandler> m_UnLinkedShips = new List<AIEventHandler>();

        private uint m_unLinkedVehcileID = 0;
        private int m_nCount = 0;

        private GameObject randomPrefab;

        private void Start() {
            m_unLinkedVehcileID = 0;
            m_UnLinkedShips.Clear();

            Camera cam = Camera.current;
            if (!cam) {
                return;
            }
            cam.nearClipPlane = 0.1f;

        }

        private void OnGUI() {
            if (!m_ShowGUI)
                return;

            //Rect rect = new Rect( 8f, 64f, 256f, 20f );
            //GUI.Label( rect, "# SHIP SPAWNER" );
            //// Enable spawning toggle
            //rect.width = 128f;
            //rect.y = rect.yMax + 4f;
            //m_EnableSpawning = GUI.Toggle( rect, m_EnableSpawning, "Enable Spawning" );

            //// Spawn interval slider
            //rect.y = rect.yMax + 4f;
            //GUI.Label( rect, "Spawn Interval: " + m_SpawnInterval );

            //rect.y = rect.yMax + 4f;
            //m_SpawnInterval = (float)GUI.HorizontalSlider( rect, m_SpawnInterval, 0.1f, 2.0f );

            //// Mob cap slider
            //rect.y = rect.yMax + 4f;
            //GUI.Label( rect, "Max Count: " + m_MaxCount );

            //rect.y = rect.yMax + 4f;
            //m_MaxCount = (int)GUI.HorizontalSlider( rect, m_MaxCount, 0, 99 );
            //// Remove All button
            //rect.y = rect.yMax + 4f;

            //if (GUI.Button( rect, "Remove All" )) {
            //    foreach (var c in FindObjectsOfType<AIEventHandler>()) {
            //        Destroy( c.gameObject );
            //    }
            //    Reset();
            //}
            //if (!test) {
            //    specialInit();
            //    test = true;
            //}
        }

        private void specialInit() {
            m_unLinkedVehcileID = 100;
            var randomSP = new Vector3(1000.0f, 7.0f, 900.0f );
            var randomPrefab = m_Prefabs[(int)(0)];
            var briShipObject = Instantiate( randomPrefab, randomSP, Quaternion.Euler( Vector3.up * 0.0f ) );
            briShipObject.name = "bship_" + 12;
            m_nCount = 1;

            GenVehicleEntity( briShipObject, (int)(0) );

        }
        private void Update() {
            if (GameEntry.Instance == null)
                return;
            //if (!test) return;

            int unlinkedCount = m_UnLinkedShips.Count;
            int shipCount = ShipsDictionary.Instance.Count();
            
            bool updateEntity = ShipsDictionary.Instance.Count() == unlinkedCount ? false : true;
            if (m_EnableSpawning && updateEntity && Time.time > m_LastUpdateTime && unlinkedCount < m_MaxCount) {
                bool canSpawn = CanSpawn();
                if (!canSpawn)
                    return;
                else if (m_unLinkedVehcileID == 0)
                    return;

                m_LastUpdateTime = Time.time + m_SpawnInterval;
                Spawn();
            }
            if (unlinkedCount > 0) {
                GameEntry.Instance.VehicleEntityManager.Update();
            }
        }

        private void Spawn() {

            ShipProperty.ShipsType type = ShipsDictionary.Instance.GetShipPropertyType( m_unLinkedVehcileID );
            var randomSP = ShipsDictionary.Instance.GetPoisition(m_unLinkedVehcileID);

            ShipTypes sType = ShipsDictionary.Instance.GetShipPrefabricateType(m_unLinkedVehcileID);
            if (sType == ShipTypes.StraddleType)
            {
                randomPrefab = m_Prefabs[(int)(type)];
            }
            else if (sType == ShipTypes.LineType)
            {
                randomPrefab = m_Prefabs[(int)(type) + 5];
            }
           
            var briShipObject = Instantiate( randomPrefab, randomSP, Quaternion.identity );
            briShipObject.name = "Ship_" + m_nCount;

            //生成广告版
            var m_billboardObj = Instantiate(m_BillBoard, randomSP+new Vector3d(0,7.38,0), Quaternion.identity);
            m_billboardObj.transform.SetParent(briShipObject.transform);
            m_billboardObj.name = "BillBoard_" + m_nCount;
          //  uint index = (ShipsDictionary.Instance.shipDic[m_unLinkedVehcileID].Id2 / 2);
            uint index = ShipsDictionary.Instance.HashCodeConvert(ShipsDictionary.Instance.shipDic[m_unLinkedVehcileID].Id);
            if (m_BillBoardSprites.Length <= index) return;
            Material material = new Material(Shader.Find("Unity Shaders Book/Billboard"));
            m_billboardObj.GetComponent<SpriteRenderer>().material = material;
            m_billboardObj.GetComponent<SpriteRenderer>().sprite = m_BillBoardSprites[index - 1];
            m_billboardObj.GetComponent<SpriteRenderer>().drawMode = SpriteDrawMode.Sliced;
            m_billboardObj.GetComponent<SpriteRenderer>().size = new Vector2(10.24f, 5.12f);
            material.SetTextureScale("_MainTex", new Vector2(1.1f, 1));
            m_billboardObj.transform.localScale = new Vector3(1f, 0.5f, 0.5f);
            m_billboardObj.gameObject.SetActive(false);
            ShipsDictionary.Instance.m_billBoardObject.Add(m_billboardObj);

            GenVehicleEntity( briShipObject, (int)(type) );
            StartCoroutine("SpawnerPostInitDown", 1.0f);
        }

        private IEnumerator SpawnerPostInitDown(float delayTime)
        {

            yield return new WaitForSeconds(delayTime);
            VehicleEntityManager.Instance.PostInitDown();
        }


        private void GenVehicleEntity( GameObject gameObj, int type ) {
            VehicleEntity entity = new VehicleEntity();
            if (entity != null && gameObj != null && GameEntry.Instance != null) {
                var briShip = gameObj.GetComponentInParent<AIEventHandler>();
                if (briShip != null) {
                    entity.Grap( m_unLinkedVehcileID, gameObj, type );
                    briShip.id = new Value_T<uint>( m_unLinkedVehcileID );

                    GameEntry.Instance.VehicleEntityManager.SpawnEntityManager( entity );
                    m_UnLinkedShips.Add( briShip );
                    briShip.Linked.AddListener( () => On_BridgeShipLinked( briShip ) );
                    GameController.TabSelect.GenTableSelectObjects();
                    DoCombineSomething( briShip.id.Get() );
                }
            }
        }

        private void DoCombineSomething(uint id) {
            if (id <= 0 )
                return;
            var shipPro = ShipsDictionary.Instance.shipDic[id];
            GameEntry.Instance.CombinedDeformationManager.DoLastThing( (uint)shipPro.Id1, (uint)shipPro.Id2,false);
        }

        private bool CanSpawn() {

            bool result = true;
            if (m_nCount < ShipsDictionary.Instance.Count()) {
                uint o = ShipsDictionary.Instance.GetDicKey( m_nCount );
                var vship = ShipsDictionary.Instance.shipDic[o];
                if (vship != null) {
                    uint vehicleID = vship.Id;
                    foreach (var v in m_UnLinkedShips) {
                        if (v.id.Get() == vehicleID) {
                            result = false;
                            break;
                        }
                    }
                    if (result) {
                        m_unLinkedVehcileID = vehicleID;
                    }
                }
                m_nCount++;
                return result;
            }
            return false;
        }

        private void On_BridgeShipLinked( AIEventHandler briShip ) {
            briShip.IsLinked = new Value_T<bool>( true );
            m_UnLinkedShips.Remove( briShip );
        }

        private void Reset() {
            m_nCount = 0;
            m_unLinkedVehcileID = 0;
            m_EnableSpawning = false;
            m_UnLinkedShips.Clear();
        }
    }
}
